#pragma once

#include "../base/auto_close.h"
#include "../base/logger.h"
#include <atomic>
#include <string>

OPEN_JLIB_NS


struct InvokeTracker {

  inline explicit InvokeTracker (const char *function_fullname) noexcept : _function_fullname(function_fullname) {
    auto layer = __layer++;
    for (auto i = 0UL; i < layer; ++i)
      _indent += "  ";
  }

  inline void open () noexcept {
    log_v("%s%s {", _indent.c_str(), _function_fullname);
  }

  inline void close () noexcept {
    --__layer;
    log_v("%s}", _indent.c_str());
  }

private:
  const char* _function_fullname;
  std::string _indent;
  static std::atomic_size_t __layer;
};


#define TRACE \
JLIB_NS::InvokeTracker __invoke_tracker__(__PRETTY_FUNCTION__); \
JLIB_NS::AutoClose<JLIB_NS::InvokeTracker> __ac_invoke_tracker__(__invoke_tracker__);


CLOSE_JLIB_NS